import json
import time
import requests
from sqlalchemy.orm import Session

from core.config import settings
from core.dependencies import get_redis_service
from core.logger import log
from db.mysql.customers import Customers
from db.mysql.dao.customers import CustomersDAO
from db.pydantic.request.call_task import CallTaskCustomerUpdateRequest
from db.pydantic.request.voice import VoiceTTSRequest, TalkStatusRequest
from services.call_task_service import get_call_task_service
from services.customers import update_customer_callState_by_phone
from utils.ali_access_token import AccessToken




def voice_tts_request(appKey, token,voice_request:VoiceTTSRequest):
    url = 'https://nls-gateway-cn-shanghai.aliyuncs.com/stream/v1/tts'
    # 设置HTTPS Headers。
    httpHeaders = {
        'Content-Type': 'application/json'
        }
    # 设置HTTPS Body。
    body = {'appkey': appKey, 'token': token,
            'text': voice_request.text,
            'format': voice_request.format,
            'sample_rate': voice_request.sample_rate,
            'voice': voice_request.voice,
            'speech_rate': voice_request.speech_rate}
    body = json.dumps(body)
    start_time = time.time()
    response = requests.post(url, data=body, headers=httpHeaders)
    end_time = time.time()
    log.info('POST request, status_code: ' + str(response.status_code) + ', cost: ' + str(end_time - start_time) + 's')
    # 处理服务端返回的响应。
    contentType = response.headers.get('Content-Type')
    body = response.content
    if 'audio/mpeg' == contentType :
        return body
    else :
        log.info('The POST request failed: ' + str(body))
        return None


class VoiceService:
    """语音服务"""
    def __init__(self):
        pass
    async def tts_voice(self,req:VoiceTTSRequest):
        """
        tts
        """
        redis_server = await get_redis_service()
        await redis_server.init_redis()
        token = await redis_server.get_ali_access_token()
        if not token:
            #获取token，从redis中获取
            token, expire_time =AccessToken.create_token(settings.ALI_ACCESS_KEY_ID, settings.ALI_ACCESS_KEY_SECRET)
            if not token:
                return None
            await redis_server.set_ali_access_token(token, expire_time)
        voice_content = voice_tts_request(appKey=settings.ALI_APP_KEY, token=token,voice_request=req)
        return voice_content

    async def store_voice_status(self,req:TalkStatusRequest,db:Session):
        """
        tts
        """
        redis_server = await get_redis_service()
        await redis_server.init_redis()
        if req.phone and req.task_id != 0:
            call_service = get_call_task_service()
            await call_service.update_task_customer_status(req.task_id, req.customer_id, CallTaskCustomerUpdateRequest(call_status=req.status),db)
            if req.status == "completed":
                await call_service.reduce_task_number(req.task_id, db)

            cust_dao = CustomersDAO(db)
            customer: Customers = cust_dao.get_customer_by_customer_id(req.customer_id)
            redis_data = {
                "customer_name": customer.customer_name,
                "task_id": req.task_id,
                "customer_id": req.customer_id,
                "phone": req.phone,
                "device_phone": req.device_phone,
                "customer_age": customer.age,
                "gender": customer.gender,
                "customer_situation":customer.customer_situation
            }
            await redis_server.set_any(f"app_talk_data:{req.device_phone}",json.dumps(redis_data),expire_time=60 * 5)

            return await redis_server.set_any(f"app_talk_status:{req.device_phone}", f"{req.phone}_{req.status.value}", expire_time=60 * 5)
        elif req.phone and req.task_id == 0:
            log.info("手动拨号",req)
            return await redis_server.set_any(f"app_talk_status:{req.device_phone}", f"{req.phone}_{req.status.value}", expire_time=60 * 5)
        return await redis_server.set_any(f"app_talk_status:{req.device_phone}", f"xx_{req.status.value}", expire_time=60 * 5)

    async def get_voice_status(self,device_phone:str):
        """
        获取通话状态
        """
        redis_server = await get_redis_service()
        await redis_server.init_redis()
        return await redis_server.get_any(f"app_talk_status:{device_phone}")





def get_voice_service():
    return VoiceService()